/*
	Copyright (C) 2010 2011 Rémi Thebault

	This program is free software; you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation; either version 3 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __pc_macrotask_h__
#define __pc_macrotask_h__

#include <list>

#include <procycle/task.h>

namespace PC {

class AtomTask;
class Link;


class MacroTask :  public Task {

	Q_OBJECT

public:
	MacroTask(Cycle* cycle, MacroTask* parent=0);

	MacroTask(AtomTask* t);

	virtual ~MacroTask();



	int lastNum() const;
	int setNum(int current);


	virtual void reset() {
		Task::reset();
		m_length = 0;
		foreach(Task* t, m_tasks) {
			t->reset();
		}
	}



	Task* resolvTask(QString r_tbsId) const;


	int taskCount() const {
		return m_tasks.count();
	}

    int deepTaskCount() const;

	Task* task(int pos) const {
		return m_tasks.at(pos);
	}

	QList<Task*> tasks() const {
		return m_tasks;
	}

	int posForTask(const Task* child) const {
		return m_tasks.indexOf(const_cast<Task*>(child));
	}


	Task::const_iterator taskBegin() const {
		return m_tasks.begin();
	}
	Task::const_iterator taskEnd() const {
		return m_tasks.end();
	}

	Task::iterator taskBegin() {
		return m_tasks.begin();
	}
	Task::iterator taskEnd() {
		return m_tasks.end();
	}





	virtual Task* createAndInsertTask(int pos);
	virtual Task* createAndAppendTask();

	virtual void deleteTask(int pos);

	void insertTask(Task* t, int pos);
	void appendTask(Task* t);
	Task* removeTask(int pos);



	QList<Task*> beginTasks();
	QList<Task*> endTasks();


	virtual void preSchedule();

	virtual void forwSchedule(Link* inLink);
	virtual void backwSchedule(Link* outLink);

	virtual void postSchedule();




	bool canIndentTask(int pos) {
		return pos > 0 && pos < m_tasks.size();
	}
	bool canIndentTask(Task* t) {
		return m_tasks.indexOf(t) > 0;
	}
	void indentTask(int pos);
	void indentTask(Task* t) {
		indentTask(m_tasks.indexOf(t));
	}


	bool canUnindentTask(int childPos, int childChildPos) {
		if (childPos >= 0 && childPos < m_tasks.size()) {
			MacroTask* mt = dynamic_cast<MacroTask*>(m_tasks.at(childPos));
			if (mt) {
				return mt->canUnindentTask(childChildPos);
			}
		}
		return false;
	}
	bool canUnindentTask(int childPos) {
		return m_parent && (childPos >= 0 && childPos < m_tasks.size());
	}
	void unindentTask(int childPos, int childChildPos);


	Task* createTaskFromElement(const QDomElement& element);

	virtual void loadFromElement (const QDomElement& element);
	virtual QDomElement saveToElement (QDomDocument& doc) const;


signals:

	void taskCreated(PC::MacroTask* parent, PC::Task* task);
	void taskWillDelete(PC::Task* task);
	void taskTransformed(PC::MacroTask* parent, int taskPos);
	void taskMoved(PC::MacroTask* parentTo, PC::Task* parentFrom, int posTo, int posFrom);

protected:

	QList<Task*>	m_tasks;

};



}

#endif /* __pc_macrotask_h__ */
